/* dsmLib.h - SH disassembler header */

/* Copyright 1994-2004 Wind River Systems, Inc. */
/*
modification history
--------------------
01o,02dec04,h_k  removed dsmInst() prototype. (SPR #104932)
01n,24feb04,h_k  added INST_AND_REG_SP.
01m,11feb04,h_k  added INST_MOV_IMM32 and INST_SC.
01l,06dec01,h_k  added difinitions for INST_POP_REG, INST_ADD_IMM_R14 and
                 INST_ADD_REG_SP.
01k,14nov00,zl   reverted previous change.
01j,14sep00,csi  FP - DSP disassemble modification
01i,10may00,hk   revised instruction macros to scan GCC 2.96 code.
01h,18apr00,rsh  add macros to support dbgRetAdrsGet in dbgArchLib.c
01g,08jun99,zl   added SH4 (SH7750) graphics support instructions
01f,08mar99,hk   merged SH-DSP defs, shifted FPU instruction type values.
01e,08aug98,kab  Fix for DSP movx insn.
01d,10jun98,knr  Added support for SH-DSP.
01e,15jun98,hk   tweaked FPU instruction types.
01d,21nov97,st   added FPU instruction type.
01c,19jun96,hk   changed itBraDispRn to itBraDispRm.
01b,25dec94,hk   added delayed slot info.
01a,24nov94,hk   written based on mc68k 01q.
*/

#ifndef __INCdsmShLibh
#define __INCdsmShLibh


#ifdef __cplusplus
extern "C" {
#endif

#include "vwModNum.h"
#include "arch/sh/ivSh.h"


/* dsmLib status codes */

#define S_dsmLib_UNKNOWN_INSTRUCTION	(M_dsmLib | 1)


/* instruction types */

#define	itComplete	 0x01	/* 0   format: "opcode"			*/
#define	itOneReg	 0x02	/* n   format: "opcode Rn"		*/
#define	itStoreCsr	 0x03	/* n   format: "opcode csr, Rn"		*/
#define	itAtOneReg	 0x04	/* n   format: "opcode @Rn"		*/
#define	itPushCsr	 0x05	/* n   format: "opcode csr,@-Rn"	*/
#define	itBraDispRm	 0x06	/* m   format: "opcode Rm"		*/
#define	itLoadCsr	 0x07	/* m   format: "opcode Rm,csr"		*/
#define	itPopCsr	 0x08	/* m   format: "opcode @Rm+,csr"	*/
#define	itTwoReg	 0x09	/* nm  format: "opcode Rm,Rn"		*/
#define	itPutRmAtRn	 0x0a	/* nm  format: "opcode Rm,@Rn"		*/
#define	itGetRnAtRm	 0x0b	/* nm  format: "opcode @Rm,Rn"		*/
#define	itMac		 0x0c	/* nm  format: "opcode @Rm+,@Rn+"	*/
#define	itPopReg	 0x0d	/* nm  format: "opcode @Rm+,Rn"		*/
#define	itPushReg	 0x0e	/* nm  format: "opcode Rm,@-Rn"		*/
#define	itPutRmAtR0Rn	 0x0f	/* nm  format: "opcode Rm,@(R0,Rn)"	*/
#define	itGetRnAtR0Rm	 0x10	/* nm  format: "opcode @(R0,Rm),Rn"	*/
#define	itGetR0AtDispRm	 0x11	/* md  format: "opcode @(disp,Rm),R0"	*/
#define	itPutR0AtDispRn	 0x12	/* nd4 format: "opcode R0,@(disp,Rn)"	*/
#define	itPutRmAtDispRn	 0x13	/* nmd format: "opcode Rm,@(disp,Rn)"	*/
#define	itGetRnAtDispRm	 0x14	/* nmd format: "opcode @(disp,Rm),Rn"	*/
#define	itPutR0AtDispGbr 0x15	/* d   format: "opcode R0,@(disp,GBR)"	*/
#define	itGetR0AtDispGbr 0x16	/* d   format: "opcode @(disp,GBR),R0"	*/
#define	itMova		 0x17	/* d   format: "opcode @(disp,PC),R0"	*/
#define	itBraDisp8	 0x18	/* d   format: "opcode disp"		*/
#define	itBraDisp12	 0x19	/* d12 format: "opcode disp"		*/
#define	itGetRnAtDispPc	 0x1a	/* nd8 format: "opcode @(disp,PC),Rn"	*/
#define	itImmAtR0Gbr	 0x1b	/* i   format: "opcode #imm,@(R0,GBR)"	*/
#define	itImmToR0	 0x1c	/* i   format: "opcode #imm,R0"		*/
#define	itImm		 0x1d	/* i   format: "opcode #imm"		*/
#define	itImmToRn	 0x1e	/* ni  format: "opcode #imm,Rn"		*/
#define itGetDispPc      0x1f   /* i   format; "opcode @(disp,PC)"      */

/* FPU Instruction types */

#define itOneFpReg	 0x20	/* fn    format: "opcode FRn"		*/
#define itTwoFpReg	 0x21	/* fnfm  format: "opcode FRm,FRn"	*/
#define itFloadFpul	 0x22	/* fm    format: "opcode FRm,FPUL"	*/
#define itFstoreFpul	 0x23	/* fn    format: "opcode FPUL,FRn"	*/
#define itThreeFpReg	 0x24	/* fnfm  format: "opcode FR0,FRm,FRn"	*/
#define itGetFRnAtR0Rm	 0x25	/* fnm   format: "opcode @(R0,Rm),FRn"	*/
#define itPopFRn	 0x26   /* fnm   format: "opcode @Rm+,FRn"	*/
#define itGetFRnAtRm	 0x27   /* fnm   format: "opcode @Rm,FRn"	*/
#define itPutFRmAtR0Rn   0x28   /* nfm   format: "opcode FRm,@(R0,Rn)"	*/
#define itPushFRm	 0x29   /* nfm   format: "opcode FRm,@-Rn"	*/
#define itPutFRmAtRn	 0x2a   /* nfm   format: "opcode FRm,@Rn"	*/
#define itLoadFpscr	 0x2b	/* m     format: "opcode Rm,FPSCR"	*/
#define itLoadFpul	 0x2c	/* m     format: "opcode Rm,FPUL"	*/
#define itPopFpscr	 0x2d   /* m     format: "opcode @Rm+,FPSCR"	*/
#define itPopFpul	 0x2e   /* m     format: "opcode @Rm+,FPUL"	*/
#define itStoreFpscr	 0x2f	/* n     format: "opcode FPSCR,Rn"	*/
#define itStoreFpul	 0x30	/* n     format: "opcode FPUL,Rn"	*/
#define itPushFpscr	 0x31   /* n     format: "opcode FPSCR,@-Rn"	*/
#define itPushFpul	 0x32   /* n     format: "opcode FPUL,@-Rn"	*/
#define itFipr           0x33	/* VnVm  format: "opcode FVm, FVn"      */
#define itFtrv           0x34	/* Vn    format: "opcode XMTRX, FVn"    */
#define itConvToDp       0x35	/* Dn    format: "opcode FPUL, DRn"     */
#define itConvToSp       0x36	/* Dm    format: "opcode DRm, FPUL"     */

#define	itDelay		0x8000	/* indicates that next inst is in delay slot */
#define	itTypeMask	0x00ff	/* mask for regular instruction types        */

typedef struct
    {
    char *name;
    int type;
    unsigned short op;
    unsigned short mask;
    } INST;


/* SH DSP instructions */
/* dsp insn flags */
#define SH_PMULS	0x00000001	/* padd/pmuls or psub/pmuls */
#define SH_DCT		0x00000002	/* dct prefix */
#define SH_DCF		0x00000004	/* dcf prefix */
#define SH_MOVS		0x00000008	/* movs.[wl] insn */
#define SH_MOVX		0x00000010	/* movx.w insn */
#define SH_MOVY		0x00000020	/* movy.w insn */

typedef enum {
	D_END=0,
	D_AS,
	D_AX,
	D_AY,
	D_DAX,
	D_DAY,
	D_DG,
	D_DS,
	D_DU,
	D_DX,
	D_DY,
	D_DZ,
	D_SE,
	D_SF,
	D_SX,
	D_SY,
	D_MACH,
	D_MACL,
	D_IMM
} SH_DSP_ARG_TYPE;

/*
 * First 16 bits are always like:
 *	111110**********
 * Second 16 bits are like:
 *	????eeffxxyygguu
 *	????eeffxxyyzzzz
 *	00001iiiiiiizzzz
 * where it's possible to have constants in any of
 *  ee, ff, xx, yy, gg, uu, zzzz
 */
#define EE_SHIFT	10
#define FF_SHIFT	8
#define GG_SHIFT	2
#define UU_SHIFT	0
#define XX_SHIFT	6
#define YY_SHIFT	4
#define ZZ_SHIFT	0
#define EE_3		(0x3 << EE_SHIFT)
#define FF_3		(0x3 << FF_SHIFT)
#define GG_3		(0x3 << GG_SHIFT)
#define UU_3		(0x3 << UU_SHIFT)
#define XX_3		(0x3 << XX_SHIFT)
#define YY_3		(0x3 << YY_SHIFT)
#define ZZ_F		(0xF << ZZ_SHIFT)


#define MOVX_MASK	(0x02ac)
#define MOVY_MASK	(0x0153)


typedef struct {
  char *name;
  SH_DSP_ARG_TYPE arg[8];
  ULONG insn;
  ULONG mask;
  ULONG flags;
} SH_DSP_OPCODE_INFO;


/* key instructions for code scanning, shared by trcLib and dbgArchLib */

#define INST_POP_REG	(0x60f6)	/* mov.l  @r15+,rm	*/
#define MASK_POP_REG	(0xf0ff)	/*			*/

#define INST_PUSH_REG	(0x2f06)	/* mov.l  rm,@-r15      */
#define MASK_PUSH_REG	(0xff0f)	/*                      */

#define INST_ADD_IMM_SP	(0x7f00)	/* add    #imm,r15      */
#define MASK_ADD_IMM_SP	(0xff00)	/*                      */

#define INST_ADD_IMM_R14 (0x7e00)	/* add    #imm,r14	*/
#define MASK_ADD_IMM_R14 (0xff00)	/*			*/

#define INST_MOV_IMM32	(0xd000)	/* mov.l  @(disp,PC),rn */
#define MASK_MOV_IMM32	(0xf000)	/*                      */

#define INST_MOV_IMM16	(0x9000)	/* mov.w  @(disp,PC),rn */
#define MASK_MOV_IMM16	(0xf000)	/*                      */

#define INST_ADD_REG_SP	(0x3f0c)	/* add    rm,r15	*/
#define MASK_ADD_REG_SP	(0xff0f)	/*			*/

#define INST_SUB_REG_SP	(0x3f08)	/* sub    rm,r15        */
#define MASK_SUB_REG_SP	(0xff0f)	/*                      */

#define INST_AND_REG_SP	(0x2f09)	/* and    rm,r15        */
#define MASK_AND_REG_SP	(0xff0f)	/*                      */

#define INST_PUSH_FP	(0x2fe6)	/* mov.l  r14,@-r15     */
#define INST_SET_FP	(0x6ef3)	/* mov    r15,r14       */
#define INST_RESTORE_SP	(0x6fe3)	/* mov    r14,r15       */
#define INST_POP_FP	(0x6ef6)	/* mov.l  @r15+,r14     */

#define INST_PUSH_PR	(0x4f22)	/* sts.l  pr,@-r15      */
#define INST_POP_PR	(0x4f26)	/* lds.l  @r15+,pr      */
#define INST_RTS	(0x000b)	/* rts                  */

/* for system call code check, shared by trcLib and wdbDbgArchLib */

#define INST_SC		(0xc300 + (INUM_TRAP_SC & 0xff))
				/* system call: trapa #2  instr on SH3 & SH4 */
				/*              trapa #61 instr on SH2 */
#define INST_SC_MASK	(0xffff)


/* function declarations */

#if defined(__STDC__) || defined(__cplusplus)

IMPORT	  int	dsmData (USHORT *binInst, int address);
IMPORT	  int	dsmNbytes (USHORT *binInst);

#else

IMPORT	  int	dsmData ();
IMPORT	  int	dsmNbytes ();

#endif	/* __STDC__ */

#ifdef __cplusplus
}
#endif

#endif /* __INCdsmShLibh */
